
#include <stdio.h>
#include <string.h>
#include "fun_time.h"


static const char mon_list[12] =
{
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};


static const char leap_mon_list[12] =
{
	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};


/*******************************************************************************
* Function Name : fun_mktime
* Description	: 时间转为时间戳
* Input 		: 
* Output		: 
* Other 		: 
* Date			: 2016.11.14
*******************************************************************************/
unsigned long fun_mktime(struct tm_s * pT)
{
	const char * pDays;
	unsigned long tmp = 0;
	unsigned char i = 0;

	//计算总共有多少个闰年
	tmp = (pT->tm_year / 4 - pT->tm_year / 100 + pT->tm_year / 400) - (1970 / 4 - 1970 / 100 + 1970 / 400);

	//如果当年是闰年，需要减去当年的闰年
	if ((pT->tm_year % 4 == 0) && ((pT->tm_year % 100 != 0) || (pT->tm_year % 400 == 0))) {
		tmp = tmp - 1 + (pT->tm_year - 1970) * 365;
		pDays = leap_mon_list;
	}
	else {
		tmp = tmp + (pT->tm_year - 1970) * 365;
		pDays = mon_list;
	}

	for (i = 0; i < pT->tm_mon - 1; i++)
		tmp += pDays[i];

	tmp = tmp + pT->tm_mday - 1;
	tmp = tmp * 24 + pT->tm_hour;
	tmp = tmp * 60 + pT->tm_min;
	tmp = tmp * 60 + pT->tm_sec;

	return tmp;
}


/*******************************************************************************
* Function Name : fun_localtime
* Description	: 时间戳转为时间
* Input 		:	struct tm_s *pT： 输出的时间缓冲区	uint32_t tim:当前时间戳
* Output		: 
* Other 		: 
* Date			: 2016.11.14
*******************************************************************************/
void fun_localtime(struct tm_s * pT, unsigned long tim)
{
	const char * pDays;
	unsigned char index = 0;

	memset(pT, 0, sizeof(*pT));
	//1970-1-1 是星期四
	pT->tm_wday = (tim / (24 * 60 * 60) + 4) % 7;
	//year initialization
	if (tim > 0x5685C180L) // 2016-1-1 0:0:0
	{
		pT->tm_year = 2016;
		tim -= 0x5685C180L;
	}
	else if (tim > 0x4B3D3B00L) // 2010-1-1 0:0:0
	{
		pT->tm_year = 2010;
		tim -= 0x4B3D3B00L;
	}
	else if (tim > 0x386D4380L) // 2000-1-1 0:0:0
	{
		pT->tm_year = 2000;
		tim -= 0x386D4380L;
	}
	else {
		pT->tm_year = 1970;
	}

	//now have year
	while (tim >= 366L * 24 * 60 * 60) {
		if ((pT->tm_year % 4 == 0) && ((pT->tm_year % 100 != 0) || (pT->tm_year % 400 == 0)))
			tim -= 366L * 24 * 60 * 60;
		else 
			tim -= 365L * 24 * 60 * 60;

		pT->tm_year++;
	}

	// then 365 * 24 * 60 * 60 < tim < 366 * 24 * 60 * 60
	if (! (((pT->tm_year % 4 == 0) && ((pT->tm_year % 100 != 0) || (pT->tm_year % 400 == 0)))) &&
		 (tim > 365L * 24 * 60 * 60)) {
		tim -= 365L * 24 * 60 * 60;
		pT->tm_year++;
	}

	// this year is a leap year?
	if (((pT->tm_year % 4 == 0) && ((pT->tm_year % 100 != 0) || (pT->tm_year % 400 == 0))))
		pDays = leap_mon_list;
	else 
		pDays = mon_list;

	pT->tm_mon = 1;

	// now have mon
	while (tim > pDays[index] *24L * 60 * 60) {
		tim -= pDays[index] *24L * 60 * 60;
		index++;
		pT->tm_mon++;
	}

	// now have days
	pT->tm_mday = tim / (24L * 60 * 60) + 1;
	tim = tim % (24L * 60 * 60);

	// now have hour
	pT->tm_hour = tim / (60 * 60);
	tim = tim % (60 * 60);

	// now have min 
	pT->tm_min = tim / 60;
	tim = tim % 60;

	pT->tm_sec = tim;
}

/*
检查时间是否合法
*/
int func_checktime(struct tm_s *tm){
	const char* pDays;
	int i;
	
	//检查年
	if(tm->tm_year < 1970){
		return 0;
	}
	
	//检查月
	if(tm->tm_mon < 1 || tm->tm_mon > 12){
		return 0;
	}
	
	//检查日
	if(tm->tm_mday < 1){
		return 0;
	}
	
	if ((tm->tm_year % 4 == 0) && ((tm->tm_year % 100 != 0) || (tm->tm_year % 400 == 0))) {
		pDays = leap_mon_list;
	}
	else {
		pDays = mon_list;
	}

	for(i = 0; i < sizeof(mon_list); i++){
		if(tm->tm_mday > pDays[i]){
			return 0;
		}
	}
	
	//时
	if(tm->tm_hour > 23){
		return 0;
	}
	
	//分
	if(tm->tm_min > 59){
		return 0;
	}
	
	//秒
	if(tm->tm_sec > 59){
		return 0;
	}
	return 1;
}


